package com.bbird.od.finance.controller;

import com.bbird.od.finance.service.models.type.BankType;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.CountDownLatch;

/**
 * @author ziyang Kuang
 * @date 2021/04/30
 * @describe
 */
public class MainController {
    private Stage stage;

    public TextField savePathTF;
    public Button savePathBtn;
    public Button startBtn;
    private String historyChooseFilePath;

    private Map<BankType, AnchorPane> paneMap = new TreeMap<>();
    private Map<String, AnchorPane> btnPaneMap = new HashMap(4);
    private Map<String, TextField> textFieldMap = new HashMap(16);
    private Map<BankType, ReconciliationDomain> prepareFileMap = new TreeMap();

    public AnchorPane jdPane;
    public AnchorPane tbPane;
    public AnchorPane pddPane;
    public AnchorPane dyPane;

    public Button jdErpFlowBtn;
    public Button jdBankFlowBtn;
    public Button jdDeliveryFlowBtn;
    public Button jdHistoryFlowBtn;

    public TextField jdErpFlowTF;
    public TextField jdBankFlowTF;
    public TextField jdDeliveryFlowTF;
    public TextField jdHistoryFlowTF;

    public TextField tbErpFlowTF;
    public TextField tbBankFlowTF;
    public TextField tbDeliveryFlowTF;
    public TextField tbHistoryFlowTF;

    public TextField pddErpFlowTF;
    public TextField pddBankFlowTF;
    public TextField pddDeliveryFlowTF;
    public TextField pddHistoryFlowTF;

    public TextField dyErpFlowTF;
    public TextField dyBankFlowTF;
    public TextField dyDeliveryFlowTF;
    public TextField dyHistoryFlowTF;

    public ProgressBar jdProgressBar;
    public ProgressBar tbProgressBar;
    public ProgressBar pddProgressBar;
    public ProgressBar dyProgressBar;

    public Label jdProcessLB;
    public Label tbProcessLB;
    public Label pddProcessLB;
    public Label dyProcessLB;

    private ReconciliationDomain jdPrepareFile = new ReconciliationDomain(BankType.JD);
    private ReconciliationDomain tbPrepareFile = new ReconciliationDomain(BankType.TM);
    private ReconciliationDomain pddPrepareFile = new ReconciliationDomain(BankType.PDD);
    private ReconciliationDomain dyPrepareFile = new ReconciliationDomain(BankType.DY);


    public void disablePane(ActionEvent evt) {
        String checkBoxId = ((CheckBox) evt.getSource()).getId();
        AnchorPane pane = btnPaneMap.get(checkBoxId);
        pane.setDisable(!pane.isDisable());
    }

    public void chooseFile(ActionEvent evt) {
        String buttonId = ((Button) evt.getSource()).getId();

        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("选择文件");
        fileChooser.getExtensionFilters().addAll(
                new FileChooser.ExtensionFilter("Excel类型", "*.xlsx", "*.xls")
        );
        if (historyChooseFilePath != null) {
            fileChooser.setInitialDirectory(new File(historyChooseFilePath));
        }
        File file = fileChooser.showOpenDialog(this.stage);
        if (file == null) {
            return;
        }
        historyChooseFilePath = file.getAbsolutePath().replace(file.getName(), "");
        String choosingFile = file.getAbsolutePath();
        textFieldMap.get(buttonId).setText(choosingFile);
    }

    public void chooseSavePath() {
        DirectoryChooser directoryChooser = new DirectoryChooser();
        if (historyChooseFilePath != null) {
            directoryChooser.setInitialDirectory(new File(historyChooseFilePath));
        }
        File file = directoryChooser.showDialog(stage);
        if (file == null) {
            return;
        }
        historyChooseFilePath = file.getAbsolutePath();
        savePathTF.setText(file.getAbsolutePath());
    }

    /**
     * 开始对账
     */
    public void reconciliationProcessing() {
        // 数据校验
        if (!verify()) {
            return;
        }

        startBtn.setDisable(true);

        long count = prepareFileMap.entrySet().stream()
                .map(Map.Entry::getKey).filter(key -> !paneMap.get(key).isDisable()).count();
        final CountDownLatch latch = new CountDownLatch(Integer.parseInt(count+""));
        // 开始对账
        prepareFileMap.forEach((type, domain) -> {
            if (!paneMap.get(type).isDisable()) {
                new Thread(() -> {
                    domain.start(this.savePathTF.getText());
                    latch.countDown();
                }).start();
            }
        });
        new Thread(()->{
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            startBtn.setDisable(false);
        }).start();
    }

    public void initPaneMap() {
        paneMap.put(BankType.JD, jdPane);
        paneMap.put(BankType.TM, tbPane);
        paneMap.put(BankType.PDD, pddPane);
        paneMap.put(BankType.DY, dyPane);

        btnPaneMap.put("jdCheckBox", jdPane);
        btnPaneMap.put("tbCheckBox", tbPane);
        btnPaneMap.put("pddCheckBox", pddPane);
        btnPaneMap.put("dyCheckBox", dyPane);

        // 初始化数据框和按钮绑定
        textFieldMap.put("jdErpFlowBtn", jdErpFlowTF);
        textFieldMap.put("jdBankFlowBtn", jdBankFlowTF);
        textFieldMap.put("jdDeliveryFlowBtn", jdDeliveryFlowTF);
        textFieldMap.put("jdHistoryFlowBtn", jdHistoryFlowTF);

        textFieldMap.put("tbErpFlowBtn", tbErpFlowTF);
        textFieldMap.put("tbBankFlowBtn", tbBankFlowTF);
        textFieldMap.put("tbDeliveryFlowBtn", tbDeliveryFlowTF);
        textFieldMap.put("tbHistoryFlowBtn", tbHistoryFlowTF);

        textFieldMap.put("pddErpFlowBtn", pddErpFlowTF);
        textFieldMap.put("pddBankFlowBtn", pddBankFlowTF);
        textFieldMap.put("pddDeliveryFlowBtn", pddDeliveryFlowTF);
        textFieldMap.put("pddHistoryFlowBtn", pddHistoryFlowTF);

        textFieldMap.put("dyErpFlowBtn", dyErpFlowTF);
        textFieldMap.put("dyBankFlowBtn", dyBankFlowTF);
        textFieldMap.put("dyDeliveryFlowBtn", dyDeliveryFlowTF);
        textFieldMap.put("dyHistoryFlowBtn", dyHistoryFlowTF);

        jdErpFlowTF.textProperty().bindBidirectional(jdPrepareFile.getErpFlow());
        jdBankFlowTF.textProperty().bindBidirectional(jdPrepareFile.getBankFlow());
        jdDeliveryFlowTF.textProperty().bindBidirectional(jdPrepareFile.getDeliveryFlow());
        jdHistoryFlowTF.textProperty().bindBidirectional(jdPrepareFile.getHistoryFlow());

        tbErpFlowTF.textProperty().bindBidirectional(tbPrepareFile.getErpFlow());
        tbBankFlowTF.textProperty().bindBidirectional(tbPrepareFile.getBankFlow());
        tbDeliveryFlowTF.textProperty().bindBidirectional(tbPrepareFile.getDeliveryFlow());
        tbHistoryFlowTF.textProperty().bindBidirectional(tbPrepareFile.getHistoryFlow());

        pddErpFlowTF.textProperty().bindBidirectional(pddPrepareFile.getErpFlow());
        pddBankFlowTF.textProperty().bindBidirectional(pddPrepareFile.getBankFlow());
        pddDeliveryFlowTF.textProperty().bindBidirectional(pddPrepareFile.getDeliveryFlow());
        pddHistoryFlowTF.textProperty().bindBidirectional(pddPrepareFile.getHistoryFlow());

        dyErpFlowTF.textProperty().bindBidirectional(dyPrepareFile.getErpFlow());
        dyBankFlowTF.textProperty().bindBidirectional(dyPrepareFile.getBankFlow());
        dyDeliveryFlowTF.textProperty().bindBidirectional(dyPrepareFile.getDeliveryFlow());
        dyHistoryFlowTF.textProperty().bindBidirectional(dyPrepareFile.getHistoryFlow());

        prepareFileMap.put(BankType.JD, jdPrepareFile);
        prepareFileMap.put(BankType.TM, tbPrepareFile);
        prepareFileMap.put(BankType.PDD, pddPrepareFile);
        prepareFileMap.put(BankType.DY, dyPrepareFile);

        jdPrepareFile.setProgressBar(jdProgressBar);
        tbPrepareFile.setProgressBar(tbProgressBar);
        pddPrepareFile.setProgressBar(pddProgressBar);
        dyPrepareFile.setProgressBar(dyProgressBar);

        jdPrepareFile.setProcessLB(jdProcessLB);
        tbPrepareFile.setProcessLB(tbProcessLB);
        pddPrepareFile.setProcessLB(pddProcessLB);
        dyPrepareFile.setProcessLB(dyProcessLB);
    }

    /**
     * 校验文件是否准备正确
     */
    private boolean verify() {
        try {
            paneMap.forEach((type, pane) -> {
                if (!pane.isDisable()) {
                    String msg = prepareFileMap.get(type).checkParam();
                    if (msg != null) {
                        throw new RuntimeException(msg);
                    }
                }
            });
        } catch (Exception e) {
            verifyAlert(e.getMessage());
            return false;
        }

        String savePath = savePathTF.getText();
        if (StringUtils.isBlank(savePath)) {
            verifyAlert("保存目录不能为空");
            return false;
        }

        return true;
    }

    private void verifyAlert(String msg) {
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("警告");
        alert.setHeaderText(msg);
        alert.showAndWait();
    }

}
